#include "dataoperat.h"

int isThreePointOnALine(const  double threex[],const  double threey[])
{
    double	k0,k1,k2;

    if (fabs(threex[0]-threex[1]) < 1e-6
            && fabs(threex[0]-threex[2]) < 1e-6
            && fabs(threex[2]-threex[1]) < 1e-6
            && fabs(threey[0]-threey[1]) < 1e-6
            && fabs(threey[0]-threey[2]) < 1e-6
            && fabs(threey[2]-threey[1]) < 1e-6 )		//三点几乎重合
    {
        //printf("1.IsThreePointOnALine\n");
        return 1;
    }
    else if ((fabs(threex[0]-threex[1]) < 1e-6 && fabs(threey[0]-threey[1]) < 1e-6)
             || (fabs(threex[0]-threex[2]) < 1e-6 && fabs(threey[0]-threey[2]) < 1e-6)
             || (fabs(threex[2]-threex[1]) < 1e-6 && fabs(threey[2]-threey[1]) < 1e-6) )
    {
        //三点间,有2点几乎重合
        if (fabs(threex[0]-threex[2]) < 1e-6 && fabs(threey[0]-threey[2]) < 1e-6)
        {
            //如果是两边2个点几乎重合,则将第2个点坐标->第3个点
            return 2;
        }
        else
        {
            //printf("2.IsThreePointOnALine\n");
            return 1;
        }
    }
    else if (fabs(threex[0]-threex[1]) < 1e-6
             && fabs(threex[0]-threex[2]) < 1e-6
             && fabs(threex[2]-threex[1]) < 1e-6 )
    {
        //三个点,X的差距极小
        //printf("3.IsThreePointOnALine\n");
        if (threey[0] < threey[2])
        {
            if (threey[1] > threey[2])
            {
                return 2;
            }
        }
        else
        {
            if (threey[1] < threey[2])
            {
                return 2;
            }
        }
        return 1;
    }
    else if (fabs(threey[0]-threey[1]) < 1e-6
             && fabs(threey[0]-threey[2]) < 1e-6
             && fabs(threey[2]-threey[1]) < 1e-6 )
    {	//三个点,Y的差距极小
        //		printf("4.IsThreePointOnALine\n");
        if (threex[0] < threex[2])
        {
            if (threex[1] > threex[2])
            {
                return 2;
            }
        }
        else
        {
            if (threex[1] < threex[2])
            {
                return 2;
            }
        }
        return 1;
    }
    else if (fabs(threex[2]-threex[1]) >= 1e-6
             && fabs(threex[2]-threex[0]) >= 1e-6
             && fabs(threex[1]-threex[0]) >= 1e-6
             && fabs(threey[2]-threey[1]) >= 1e-6
             && fabs(threey[2]-threey[0]) >= 1e-6
             && fabs(threey[1]-threey[0]) >= 1e-6 )
    {
        k0 = (threey[2]-threey[1])/(threex[2]-threex[1]);
        k1 = (threey[2]-threey[0])/(threex[2]-threex[0]);
        k2 = (threey[1]-threey[0])/(threex[1]-threex[0]);

        if(fabs(k0-k1) < 1e-6 && fabs(k1-k2) < 1e-6)
        {
            //三个点,2点之间的斜率差极小
            //printf("5.IsThreePointOnALine\n");
            if ( (threex[0] < threex[1] && threex[1] < threex[2] )
                 || (threex[0] > threex[1] && threex[1] > threex[2]))
            {
            }
            else
            {
                return 2;
            }

            return 1;
        }
        else
        {
            //printf("6.IsThreePointOnALine\n");
            return 0;
        }
    }
    else
    {
        //printf("7.IsThreePointOnALine\n");
        return 0;
    }
}

int getArcCenter(const double x[], const double y[], double * pxc, double * pyc, double * pr)
{
#if 0
    double x20, x21, xh0, xh1, y20, y21, yk0, yk1;
    double x2y20, x2y21, xnyn, ykn;

    double xx0,xx1,xx2;
    double yy0,yy1,yy2;
    xx0=x[0];
    yy0=y[0];
    xx1=x[1];
    yy1=y[1];
    xx2=x[2];
    yy2=y[2];

    if(fabs(xx0-xx1)<1e-6)
    {
        yc=(yy0+yy1)/2;
        xc=(xx0*xx0-xx2*xx2+yy0*yy0-yy2*yy2+2*yy2*yc-2*yy0*yc)/(2*xx0-2*xx2);
        r=sqrt((xx0-xc)*(xx0-xc)+(yy0-yc)*(yy0-yc));
    }
    else if(fabs(xx0-xx2)<1e-6)
    {
        yc=(yy0+yy2)/2;
        xc=(xx0*xx0-xx1*xx1+yy0*yy0-yy1*yy1+2*yy1*yc-2*yy0*yc)/(2*xx0-2*xx1);
        r=sqrt((xx0-xc)*(xx0-xc)+(yy0-yc)*(yy0-yc));
    }
    else if(fabs(xx1-xx2)<1e-6)
    {
        yc=(yy1+yy2)/2;
        xc=(xx1*xx1-xx0*xx0+yy1*yy1-yy0*yy0+2*yy0*yc-2*yy1*yc)/(2*xx1-2*xx0);
        r=sqrt((xx0-xc)*(xx0-xc)+(yy0-yc)*(yy0-yc));
    }
    else if(fabs(yy0-yy1)<1e-6)
    {
        xc=(xx0+xx1)/2;
        yc=(yy0*yy0-yy2*yy2+xx0*xx0-xx2*xx2+2*xx2*xc-2*xx0*xc)/(2*yy0-2*yy2);
        r=sqrt((xx0-xc)*(xx0-xc)+(yy0-yc)*(yy0-yc));
    }
    else if(fabs(yy0-yy2)<1e-6)
    {
        xc=(xx0+xx2)/2;
        yc=(yy0*yy0-yy1*yy1+xx0*xx0-xx1*xx1+2*xx1*xc-2*xx0*xc)/(2*yy0-2*yy1);
        r=sqrt((xx0-xc)*(xx0-xc)+(yy0-yc)*(yy0-yc));
    }
    else if(fabs(yy1-yy2)<1e-6)
    {
        xc=(xx1+xx2)/2;
        yc=(yy1*yy1-yy0*yy0+xx1*xx1-xx0*xx0+2*xx0*xc-2*xx1*xc)/(2*yy1-2*yy0);
        r=sqrt((xx0-xc)*(xx0-xc)+(yy0-yc)*(yy0-yc));
    }
    else
    {
        x20=xx0*xx0-xx1*xx1;
        xh0=2*xx0-2*xx1;
        y20=yy0*yy0-yy1*yy1;
        yk0=2*yy0-2*yy1;

        x21=xx1*xx1-xx2*xx2;
        xh1=2*xx1-2*xx2;
        y21=yy1*yy1-yy2*yy2;
        yk1=2*yy1-2*yy2;

        x2y20=x20+y20;
        x2y21=x21+y21;

        xnyn=x2y20;
        ykn=yk0;

        x2y20 *= xh1;
        yk0 *= xh1;

        x2y21 *= xh0;
        yk1 *= xh0;

        yc = (x2y20-x2y21)/(yk0-yk1);
        xc = (xnyn-yc*ykn)/xh0;

        xx0 -= xc;
        yy0 -= yc;

        r=sqrt(xx0*xx0+yy0*yy0);
    }

#else

    double a, b, c, d, e, f;
    double xc, yc, r;

    if (isThreePointOnALine(x, y) >= 1)
    {
        return -1;
    }

    a = 2 * (x[1]-x[0]);
    b = 2 * (y[1]-y[0]);
    c = x[1]*x[1] + y[1]*y[1] - x[0]*x[0] - y[0]*y[0];
    d = 2 * (x[2]-x[1]);
    e = 2 * (y[2]-y[1]);
    f = x[2]*x[2] + y[2]*y[2] - x[1]*x[1] - y[1]*y[1];

    xc = (b*f-e*c)/(b*d-e*a);
    yc = (d*c-a*f)/(b*d-e*a);
    r = sqrt((xc-x[0])*(xc-x[0])+(yc-y[0])*(yc-y[0]));
#endif

    *pxc = xc;
    *pyc = yc;
    *pr = r;

    return 0;
}

int getArcMinMax(const double x[], const double y[], double * pminx, double * pmaxx, double * pminy, double * pmaxy)
{
    double k, xc, yc, r;
    int beg = 0;
    int mid = 0;
    int end = 0;
    double minx, miny, maxx, maxy;

    getArcCenter(x, y, &xc, &yc, &r);
    //	printf("cx=%f, cy=%f, r=%f\n", xc, yc, r);
    // 区分象限和方向
    k = (x[0]-x[1])*(x[2]-x[1]) + (y[0]-y[1])*(y[2]-y[1]);		// 向量 01 和 向量 21 的夹角的余弦的符号--
    //	> 0 小于90度 向量夹角小于90度, 说明弧是大于半圆
    //	< 0 大于90度 向量夹角大于90度, 说明弧是小于半圆
    //	= 0 90 度 向量夹角等于90度, 说明弧是半圆

    if (x[0] > xc && y[0] > yc)		// 起点在第一象限
    {
        beg = 1;
    }
    else if (x[0] < xc && y[0] > yc)	// 起点在第二象限
    {
        beg = 2;
    }
    else if (x[0] < xc && y[0] < yc)	// 起点在第三象限
    {
        beg = 3;
    }
    else if (x[0] > xc && y[0] < yc)	// 起点在第四象限
    {
        beg = 4;
    }
    else if (fabs(y[0]-yc) < 1e-6)		// 起点在x轴上
    {
        if (x[0] > xc)
        {
            beg = 5;		// x正半轴
        }
        else
        {
            beg = 6;		// x负半轴
        }
    }
    else if (fabs(x[0]-xc) < 1e-6)		// 起点在y轴上
    {
        if (y[0] > yc)
        {
            beg = 7;	// y正半轴
        }
        else
        {
            beg = 8;	// y正半轴
        }
    }
    else
    {
        printf("this is an new selection for first point\n");
    }

    if (x[1] > xc && y[1] > yc)		// 中点在第一象限
    {
        mid = 1;
    }
    else if (x[1] < xc && y[1] > yc)	// 中点在第二象限
    {
        mid = 2;
    }
    else if (x[1] < xc && y[1] < yc)	// 中点在第三象限
    {
        mid = 3;
    }
    else if (x[1] > xc && y[1] < yc)	// 中点在第四象限
    {
        mid = 4;
    }
    else if (fabs(y[1]-yc)<1e-6)		// 中点在x轴上
    {
        if (x[1] > xc)	{mid = 5;}		// x正半轴
        else{	mid = 6;	}			// x负半轴
    }
    else if (fabs(x[1]-xc)<1e-6)		// 中点在y轴上
    {
        if (y[1] > yc)		// y正半轴
        {
            mid = 7;
        }
        else	{	mid = 8;	}		// y负半轴
    }
    else
    {
        printf("this is an new selection for second point\n");
    }

    if (x[2] > xc && y[2] > yc)		// 终点在第一象限
    {
        end = 1;
    }
    else if (x[2] < xc && y[2] > yc)	// 终点在第二象限
    {
        end = 2;
    }
    else if (x[2] < xc && y[2] < yc)	// 终点在第三象限
    {
        end = 3;
    }
    else if (x[2] > xc && y[2] < yc)	// 终点在第四象限
    {
        end = 4;
    }
    else if (fabs(y[2]-yc)<1e-6)		// 终点在x轴上
    {
        if (x[2] > xc)	{end = 5;}		// x正半轴
        else{end = 6;}					// x负半轴
    }
    else if (fabs(x[2]-xc)<1e-6)		// 终点在y轴上
    {
        if (y[2] > yc){	end = 7;}		// y正半轴
        else{end = 8;}					// y负半轴
    }
    else
    {
        printf("this is an new selection for third point\n");
    }

    minx = S32_MAX;
    maxx = S32_MIN;
    miny = S32_MAX;
    maxy = S32_MIN;

    switch (beg)
    {
    case 1:	// 起点在第一象限内
    {
        switch (end)
        {
        case 1:	// 终点在第一象限内
        case 5:	// 终点在x正半轴上
        case 7:	// 终点在y正半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = xc + r;
                miny = yc - r;
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("1 Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 2:	// 终点在第二象限内
        case 6:	// 终点在x负半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = xc + r;
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else 		// 半弧
            {
                printf("2 Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 3:	// 终点在第三象限内
            if (mid == 2 || mid == 6 || mid == 7 || (mid == 1 && x[1] < x[0]) || (mid == 3 && x[1] < x[2]))		// 逆时针方向
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else if (mid == 4 || mid == 5 || mid == 8 || (mid == 1 && x[1] > x[0]) || (mid == 3 && x[1] > x[2]))	// 顺时针方向
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else
            {
                printf("3. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 4:	// 终点在第四象限内
        case 8:	// 终点在y负半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
                miny = yc - r;
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
                miny = MIN(y[0], y[2]);
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("4. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        default:
            break;
        }

        break;
    }
    case 2:	// 起点在第二象限内
    {
        switch (end)
        {
        case 1:	// 终点在第一象限内
        case 5:	// 终点在x正半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = xc + r;
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else 		// 半弧
            {
                printf("5. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 2:	// 终点在第二象限内
        case 6:	// 终点在x负半轴上
        case 7:	// 终点在y正半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = xc + r;
                miny = yc - r;
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("6. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 3:	// 终点在第三象限内
        case 8:	// 终点在y负半轴上
            if (k > 0)			// 大半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
                miny = yc - r;
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("7. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 4:	// 终点在第四象限内
            if (mid == 3 || mid == 6 || mid == 8 || (mid == 2 && x[1] < x[0]) || (mid == 4 && x[1] < x[2]))		// 逆时针方向
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else if (mid == 1 || mid == 5 || mid == 7 || (mid == 2 && x[1] > x[0]) || (mid == 4 && x[1] > x[2]))	// 顺时针方向
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else
            {
                printf("8. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        default:
            break;
        }
        break;
    }
    case 3:	// 起点在第三象限内
    {
        switch (end)
        {
        case 1:	// 终点在第一象限内
            if (mid == 4 || mid == 5 || mid == 8 || (mid == 1 && x[1] > x[0]) || (mid == 3 && x[1] > x[2]))		// 逆时针方向
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else if (mid == 2 || mid == 6 || mid == 7 || (mid == 1 && x[1] < x[0]) || (mid == 3 && x[1] < x[2]))	// 顺时针方向
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else
            {
                printf("9. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 2:	// 终点在第二象限内
        case 7:	// 终点在y正半轴上
            if (k > 0)			// 大半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
                miny = yc - r;
                maxy = yc + r;
            }
            else if (k < 0)		// 小半弧
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("10. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	 // 不可能出现的情况
            }
            break;
        case 3:	// 终点在第三象限内
        case 6:	// 终点在x负半轴上
        case 8:	// 终点在y负半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = xc + r;
                miny = yc - r;
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("11. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	 // 不可能出现的情况
            }
            break;
        case 4:	// 终点在第四象限内
        case 5:	// 终点在x正半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = xc + r;
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = MAX(x[0], x[2]);
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("12. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        default:
            break;
        }
        break;
    }
    case 4:	// 起点在第四象限内
    {
        switch (end)
        {
        case 1:	// 终点在第一象限内
        case 7:	// 终点在y正半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
                miny = yc - r;
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
                miny = MIN(y[0], y[2]);
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("13. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 2:	// 终点在第二象限内
            if (mid == 1 || mid == 5 || mid == 7 || (mid == 2 && x[1] > x[0]) || (mid == 4 && x[1] > x[2]))		// 逆时针方向
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else if (mid == 3 || mid == 6 || mid == 8 || (mid == 2 && x[1] < x[0]) || (mid == 4 && x[1] < x[2]))	// 顺时针方向
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else
            {
                printf("14. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 3:	// 终点在第三象限内
        case 6:	// 终点在x负半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = xc + r;
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = MAX(x[0], x[2]);
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("15. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 4:	// 终点在第四象限内
        case 5:	// 终点在x正半轴上
        case 8:	// 终点在y负半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = xc + r;
                miny = yc - r;
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("16. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        default:
            break;
        }
        break;
    }
    case 5:	// 起点在在x正半轴上
    {
        maxx = xc + r;

        switch (end)
        {
        case 1:	// 终点在第一象限内
        case 4:	// 终点在第四象限内
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                miny = yc - r;
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("17. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 2:	// 终点在第二象限内
        case 7:	// 终点在y正半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else 		// 半弧
            {
                printf("18. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 3:	// 终点在第三象限内
        case 8:	// 终点在y负半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("19. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 5:	// 终点在x正半轴上
            printf("20. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            break;

        case 6:	// 终点在x负半轴上
            minx = xc - r;
            if (y[1] > yc)	// 逆时针
            {
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else if (y[1] < yc)	// 顺时针
            {
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else
            {
                printf("21. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        default:
            break;
        }
        break;
    }
    case 6:	// 起点在x负半轴上
    {
        minx = xc - r;

        switch (end)
        {
        case 1:	// 终点在第一象限内
        case 7:	// 终点在y正半轴上
            if (k > 0)			// 大半弧
            {
                maxx = xc + r;
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else if (k < 0)	// 小半弧
            {
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else 		// 半弧
            {
                printf("22. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 2:	// 终点在第二象限内
        case 3:	// 终点在第三象限内
            if (k > 0)			// 大半弧
            {
                maxx = xc + r;
                miny = yc - r;
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("23. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 4:	// 终点在第四象限内
        case 8:	// 终点在y负半轴上
            if (k > 0)			// 大半弧
            {
                maxx = xc + r;
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                maxx = MAX(x[0], x[2]);
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("24. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 5:	// 终点在x正半轴上
            maxx = xc + r;
            if (y[1] > yc)	// 顺时针
            {
                miny = MIN(y[0], y[2]);
                maxy = yc + r;
            }
            else if (y[1] < yc)	// 逆时针
            {
                miny = yc - r;
                maxy = MAX(y[0], y[2]);
            }
            else
            {
                printf("25. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 6:	// 终点在x负半轴上
            printf("26. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            break;

        default:
            break;
        }
        break;
    }

    case 7:	// 起点在y正半轴上
    {
        maxy = yc + r;

        switch (end)
        {

        case 1:	// 终点在第一象限内
        case 2:	// 终点在第二象限内
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = xc + r;
                miny = yc - r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("27. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 3:	// 终点在第三象限内
        case 6:	// 终点在x负半轴上
            if (k > 0)			// 大半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
                miny = yc - r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
                miny = MIN(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("28. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 4:	// 终点在第四象限内
        case 5:	// 终点在x正半轴上
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
                miny = yc - r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
                miny = MIN(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("29. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;

        case 7:	// 终点在y正半轴上
            printf("30. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            break;

        case 8:	// 终点在y负半轴上
            miny = yc - r;
            if (x[1] > xc)	// 顺时针
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
            }
            else if (x[1] < xc)	// 逆时针
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
            }
            else
            {
                printf("31. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;
        default:
            break;
        }
        break;
    }
    case 8:	// 起点在y负半轴上
    {
        miny = yc - r;
        switch (end)
        {
        case 1:	// 终点在第一象限内
        case 5:	// 终点在x正半轴上
        {
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("32. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;
        }
        case 2:	// 终点在第二象限内
        case 6:	// 终点在x负半轴上
        {
            if (k > 0)			// 大半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("33. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;
        }
        case 3:	// 终点在第三象限内
        case 4:	// 终点在第四象限内
        {
            if (k > 0)			// 大半弧
            {
                minx = xc - r;
                maxx = xc + r;
                maxy = yc + r;
            }
            else if (k < 0)	// 小半弧
            {
                minx = MIN(x[0], x[2]);
                maxx = MAX(x[0], x[2]);
                maxy = MAX(y[0], y[2]);
            }
            else 		// 半弧
            {
                printf("34. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;
        }
        case 7:	// 终点在y正半轴上
        {
            maxy = yc + r;

            if (x[1] > xc)		// 逆时针
            {
                minx = MIN(x[0], x[2]);
                maxx = xc + r;
            }
            else if (x[1] < xc)	// 顺时针
            {
                minx = xc - r;
                maxx = MAX(x[0], x[2]);
            }
            else
            {
                printf("35. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            }
            break;
        }
        case 8:	// 终点在y负半轴上
        {
            printf("36. Impossible in GetMinMax. beg=%d, end=%d\n", beg, end);	// 不可能出现的情况
            break;
        }
        default:
            break;
        }
        break;
    }

    default:
        break;
    }

    if (minx < *pminx)
    {
        *pminx = minx;
    }

    if (miny < *pminy)
    {
        *pminy = miny;
    }

    if (maxx > *pmaxx)
    {
        *pmaxx = maxx;
    }

    if (maxy > *pmaxy)
    {
        *pmaxy = maxy;
    }

    //	printf("minx=%.2f, maxx=%.2f, miny=%.2f, maxy=%.2f\n", minx, maxx, miny, maxy);
    return 0;
}

void rotatec(double xin, double yin, double * px, double * py, double angle)
{
    *px=xin*cos(angle)-yin*sin(angle);
    *py=xin*sin(angle)+yin*cos(angle);
}

int arcDir(const double x[], const double y[])
{
    double k;
    if(x[1] > x[0])
    {
        k = (y[1] - y[0]) / (x[1]-x[0]);
        if (y[2] < (k*(x[2]-x[1]) + y[1]))
        {
            return -1;
        }
        else
        {
            return 1;
        }
    }
    else if (x[1] < x[0])
    {
        k = (y[1] - y[0]) / (x[1] - x[0]);
        if (y[2] < (k * (x[2]-x[1]) + y[1]))
        {
            return 1;
        }
        else
        {
            return -1;
        }
    }
    else if ( (x[2]>x[1] && y[1]<y[0]) || (x[2]<x[1] && y[0]<y[1]) )
    {
        return 1;
    }
    else if ( (x[2]>x[1] && y[1]>y[0]) || (x[2]<x[1] && y[0]>y[1]) )
    {
        return -1;
    }
    else
    {
        printf("1. what's this case?\n");
        return 0;
    }
}

Point2D pointOnCubicBezier(Point2D* cp, double t)
{
#if(1)
    double ax, bx, cx; double ay, by, cy;
    double tSquared, tCubed; Point2D result;

    /* 计算多项式系数 */
    cx = 3.0 * (cp[1].x - cp[0].x);
    bx = 3.0 * (cp[2].x - cp[1].x) - cx;
    ax = cp[3].x - cp[0].x - cx - bx;
    cy = 3.0 * (cp[1].y - cp[0].y);
    by = 3.0 * (cp[2].y - cp[1].y) - cy;
    ay = cp[3].y - cp[0].y - cy - by;

    /* 计算t位置的点值 */
    tSquared = t * t;
    tCubed = tSquared * t;
    result.x =((ax * tCubed) + (bx * tSquared) + (cx * t) + cp[0].x);
    result.y =((ay * tCubed) + (by * tSquared) + (cy * t) + cp[0].y);
    return result;
#endif
}

void computeBezier(Point2D* cp, long numberOfPoints, Point2D* curve)
{
    double dt; long i;
    dt = 1.0 / ( numberOfPoints - 1 );
    for( i = 0; i < numberOfPoints; i++)
    {
        curve[i] = pointOnCubicBezier( cp, i*dt );
    }
}

int getBezierMinMax(const double x[], const double y[], double * pminx, double * pmaxx, double * pminy, double * pmaxy)
{
    long k = 0;
    double sx,sy;
    long i = 0;
    double minx, miny, maxx, maxy;
    Point2D cp[4];

    //传递参数
    for (i = 0; i <4;i++)
    {
        cp[i].x = x[i];
        cp[i].y = y[i];
    }

    //求控制点总长
    for (i = 0; i <3;i++)
    {
        sx = cp[i+1].x - cp[i].x;
        sy = cp[i+1].y - cp[i].y ;
        k +=  sqrt(sx*sx+sy*sy);  //分割点数= 总长(精度为0.1mm)
    }
    if(k == 0)
    {
        return -1;
    }

    if (k > 100)	//对多100个点
    {
        k = 100;
    }

    Point2D curve[k];

    computeBezier(cp, k, curve);	//分割针步

    minx = S32_MAX;
    maxx = S32_MIN;
    miny = S32_MAX;
    maxy = S32_MIN;

    //判断始末点
    for (i = 0; i <4;i =i+3)
    {
        if (minx > cp[i].x)
        {
            minx = cp[i].x;
        }
        if (maxx < cp[i].x)
        {
            maxx = cp[i].x;
        }
        if (miny > cp[i].y)
        {
            miny = cp[i].y;
        }
        if (maxy < cp[i].y)
        {
            maxy = cp[i].y;
        }
    }

    for (i=0;i<k;i++)
    {
        if (minx > curve[i].x)
        {
            minx = curve[i].x;
        }
        if (maxx < curve[i].x)
        {
            maxx = curve[i].x;
        }
        if (miny > curve[i].y)
        {
            miny = curve[i].y;
        }
        if (maxy < curve[i].y)
        {
            maxy = curve[i].y;
        }
    }

    //printf("\n BSR	minx = %f, maxx = %f, miny = %f, maxy = %f \n",minx,maxx,miny,maxy);

    if (minx < *pminx)
    {
        *pminx = minx;
    }

    if (miny < *pminy)
    {
        *pminy = miny;
    }

    if (maxx > *pmaxx)
    {
        *pmaxx = maxx;
    }

    if (maxy > *pmaxy)
    {
        *pmaxy = maxy;
    }

    return 0;
}

int calcLine(double x0, double y0, double x1, double y1, s16 step, QByteArray &absAry, WORD datatype)
{
    DsAbsItem absItem;
    memset(&absItem,0,sizeof(DsAbsItem));

    s32 dx, dy;
    double length;
    double tmp;
    int count;
    int i;
    double stepx, stepy;
    double sx, sy;
    int actx, acty;
    double k;

    if(x0 == x1 && y0 == y1)
    {
        return 0;
    }

    if(x0 > x1)
    {
        sx = -1.0;				// x反向
    }
    else
    {
        sx = 1.0;
    }

    if(y0 > y1)
    {
        sy = -1.0;				// y反向
    }
    else
    {
        sy = 1.0;
    }

    if(datatype == QUI_TYPE_STEP || datatype == QUI_TYPE_HSTEP)		// 跨步或翻头跨步
    {
        absItem.ctrl = DATA_OFFSET;
    }
    else
    {
        absItem.ctrl = DATA_SEWING;				// 其他
    }

    // 开始分割针步
    length = sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1));

    tmp = length/step;		/* 实际针步数 */
    count = floor(tmp);		/* 最少整针步数 */

    if (tmp - count > 0.01)
    {
        count += 1;
    }

    if (count == 0 && length > 0)	// 短直线
    {
        count = 1;
    }

    tmp = 0;
    actx = x0;
    acty = y0;

    if (x1 != x0 && y1 == y0)				// 横直线
    {
        for (i = 0; i < count; i++)
        {
            tmp = ((i+1)*(length)/count)*sx+x0;	// 实际针步

            stepx = tmp - actx;
            dx = (s32)(stepx+0.5*sx);
            dy = 0;
            actx += dx;

            absItem.ax = tmp;
            absItem.ay = y0;
            absAry.append((char*)&absItem,sizeof(DsAbsItem));
        }
    }
    else if (x1 == x0 && y1 != y0)			// 竖直线
    {
        for (i = 0; i < count; i++)
        {
            tmp = ((i+1)*(length)/count)*sy + y0;	// 实际针步

            stepy = tmp - acty;

            dx = 0;
            dy = (s32)(stepy+0.5*sy);
            acty += dy;

            absItem.ax = x0;
            absItem.ay = tmp;
            absAry.append((char*)&absItem,sizeof(DsAbsItem));
        }
    }
    else if(x1 != x0 && y1 != y0)			 // 任意斜线
    {
        k = (y1-y0)/(x1-x0);
        for (i = 0; i < count; i++)
        {
            tmp = ((i+1)*(length)/count);

            stepx = fabs(tmp*cos(atan(k)))*sx + x0;	// 实际针步x
            stepy = fabs(tmp*sin(atan(k)))*sy + y0;	// 实际针步y

            dx = (s32)(stepx-actx+0.5*sx);
            dy = (s32)(stepy-acty+0.5*sy);

            actx += dx;
            acty += dy;

            absItem.ax = stepx;
            absItem.ay = stepy;
            absAry.append((char*)&absItem,sizeof(DsAbsItem));
        }
    }
    else
    {
        printf("what's this?\n");
    }

    return count;
}

int calcCurve(double threex[], double threey[], s16 step, QByteArray &absAry)
{
    DsAbsItem absItem;
    memset(&absItem,0,sizeof(DsAbsItem));

    BYTE dx, dy;
    int count = 0;
    int i;
    s32 ar = 0;

    double distance, k;
    double alph;
    double increment;
    double xc=0,yc=0,r=0;
    int actx, acty;
    int ddx, ddy;

    i = isThreePointOnALine(threex, threey);
    if(i == 1)	// 3点共线
    {
        return calcLine(threex[0], threey[0], threex[2], threey[2], step, absAry, QUI_TYPE_LINE);	// 作为直线
    }
    else if (i == 2)
    {
        return calcLine(threex[0], threey[0], threex[1], threey[1], step, absAry, QUI_TYPE_LINE);	// 作为直线
    }

    getArcCenter(threex, threey, &xc, &yc, &r);

    //	printf("center=%.2f,%.2f,r=%.2f\n", xc, yc, r);

    // 计算弦长和圆心角
    distance = sqrt((threex[0]-threex[2])*(threex[0]-threex[2])+(threey[0]-threey[2])*(threey[0]-threey[2]));	// 两点间距离就是弦长
    k = (r*r+r*r-distance*distance)/(r*r+r*r);
    if (k < -1)
    {
        k = -1;
    }
    else if (k > 1)
    {
        k = 1;
    }

    //	printf("distance=%f, k=%f\n", distance, k);

    alph = acos(k);

    // 区分象限和方向
    k = (threex[0]-threex[1])*(threex[2]-threex[1]) + (threey[0]-threey[1])*(threey[2]-threey[1]);	// 向量 01 和 向量 21 的夹角的余弦的符号-- > 0 小于90度. < 0 大于90度 = 0, 90 度
    if (k > 0)	// 夹角小于90度, 说明弧是大于半圆
    {
        alph = 2*PI-alph;
    }
    else	// 夹角大于等于90度, 说明弧是小于等于半圆, 不需要处理
    {
    }

    //	printf("act alph=%f\n", alph);

    // 计算每个针步对应的弧心角大小
    if (fabs(2*r*r-step*step)/(2*r*r) > 1)
    {
        increment = alph;
    }
    else
    {
        increment = (acos((2*r*r-step*step)/(r*r+r*r)));
    }

    // 计算分割针步数
    count = (int)(alph/increment+0.5);
    if (count == 0)
    {
        count++;
    }

    //	printf("1.count=%d, increment=%f\n", count, increment);

    increment = alph/count;					// 重新计算每个针步弧心角

    increment *= arcDir(threex, threey);	// 确定针步增加的角度和方向

    //	printf("2.count=%d, increment=%f\n", count, increment);

    double curx, cury, lastx, lasty;
    double xrot, yrot;

    lastx = threex[0];
    lasty = threey[0];

    i = 0;

    actx = (int)(lastx);
    acty = (int)(lasty);

    do
    {
        if (i == count-1)
        {
            // 最后一个针步
            //	printf("the last step\n");
            curx = threex[2];
            cury = threey[2];
        }
        else
        {
            // 点 (lastx, lasty) 在圆上旋转
            //	printf("before Rotatec point(%f, %f)\n", lastx, lasty);

            rotatec(lastx-xc, lasty-yc, &xrot, &yrot, increment);
            curx = xrot + xc;
            cury = yrot + yc;
        }

        ddx = curx-actx;
        ddy = cury-acty;

        dx = (s16)(curx-actx+(0.5*(ddx>=0?1:-1)));
        dy = (s16)(cury-acty+(0.5*(ddy>=0?1:-1)));

        absItem.ctrl = DATA_SEWING;
        absItem.ax = curx;
        absItem.ay = cury;

        double tar = atan2(dy,dx);
        ar = (tar * 10000+0.5*(tar>0?1:-1));
        absItem.ar = ar;
        absAry.append((char*)&absItem,sizeof(DsAbsItem));

        lastx = curx;
        lasty = cury;

        actx += dx;
        acty += dy;
        i++;

    } while(i < count);

    return count;
}

#define	 YUFENGE 20                     //预分割步数
#define	 YUFENGE_BEGIN (YUFENGE*7/10)           //扫描起点

int calcBezier(double threex[], double threey[], s16 step, QByteArray &absAry)
{  
    DsAbsItem absItem;
    memset(&absItem,0,sizeof(DsAbsItem));

    int dx, dy;
    long k = 0;
    double sx,sy;
    long i , l;
    Point2D cp[4];
    int count = 0;
    double curx, cury, lastx, lasty;
    int actx, acty;
    int ddx, ddy;
    s32 ar = 0;

    //传递参数
    for (i = 0; i <4;i++)
    {
        cp[i].x = threex[i];
        cp[i].y = threey[i];
    }

    //求控制点总长
    for (i = 0; i <3;i++)
    {
        sx = cp[i+1].x - cp[i].x;
        sy = cp[i+1].y - cp[i].y ;
        k +=  sqrt(sx*sx+sy*sy);  //分割点数= 总长(精度为0.1mm)
    }

    k = (long)((k / step)+1) * YUFENGE; 	//预分割针步数,设置针步数*YUFENGE.
    Point2D curve[k];

    double dt;
    dt = 1.0 / ( k - 1 );		//分割分辨率

    lastx = cp[0].x;
    lasty = cp[0].y;

    for (i = YUFENGE_BEGIN ;i < k ; )
    {
        curve[i] = pointOnCubicBezier(cp, i*dt);
        sx = curve[i].x - lastx;
        sy = curve[i].y - lasty;
        l =  sqrt(sx*sx+sy*sy);  //拟合针步长度

        if(i == k-1)
        {
            //最后一针
            actx = (int)(lastx);
            acty = (int)(lasty);
            curx = (int)(cp[3].x);
            cury = (int)(cp[3].y);

            ddx = curx-actx;
            ddy = cury-acty;

            dx = (int)(abs(ddx)+0.5);
            dy = (int)(abs(ddy)+0.5);

            lastx = curx;
            lasty = cury;

            absItem.ctrl = DATA_SEWING;
            absItem.ax = curx;
            absItem.ay = cury;

            double tar = atan2(dy,dx);
            ar = (tar * 10000+0.5*(tar>0?1:-1));
            absItem.ar = ar;

            absAry.append((char*)&absItem,sizeof(DsAbsItem));

            count++;
            break;
        }
        else if(l >= (step-1))
        {
            actx = (int)(lastx);
            acty = (int)(lasty);
            curx = (int)(curve[i].x);
            cury = (int)(curve[i].y);

            ddx = curx-actx;
            ddy = cury-acty;

            dx = (int)(abs(ddx)+0.5);
            dy = (int)(abs(ddy)+0.5);

            lastx = curx;
            lasty = cury;
            count++;

            if ((i + YUFENGE_BEGIN) >= k-1)
            {
                i = k-1;
            }
            else
            {
                i=i+YUFENGE_BEGIN;
            }

            absItem.ctrl = DATA_SEWING;
            absItem.ax = curx;
            absItem.ay = cury;

            double tar = atan2(dy,dx);
            ar = (tar * 10000+0.5*(tar>0?1:-1));
            absItem.ar = ar;

            absAry.append((char*)&absItem,sizeof(DsAbsItem));
        }
        else
        {
            i++;
        }
    }

    return count;
}

void getSplineNew(QList<QPointF> &ptList, QList<QPointF> &splineList)
{
    //读取样条线拟合控制点
    QPointF pSuPoint;
    int i = 0;
    int iCountPoint = ptList.size();

    //绘制二次累加弦长曲线
    QPointF pPoint[iCountPoint];
    double dfMinX, dfMinY;

    dfMinX = dfMinY=  0;

    while (i < iCountPoint)
    {
        pSuPoint = ptList.at(i);

        pPoint[i].setX(pSuPoint.x());
        pPoint[i].setY(pSuPoint.y());
        if (i == 0)
        {
            dfMinX =  pPoint[i].x();
            dfMinY =  pPoint[i].y();
        }
        else
        {
            if (dfMinX > pPoint[i].x())
                dfMinX = pPoint[i].x();

            if (dfMinY > pPoint[i].y())
                dfMinY = pPoint[i].y();
        }
        i++;
    }

    for (i = 0; i < iCountPoint; i++)
    {
        double x = pPoint[i].x() - dfMinX;
        double y = pPoint[i].y() - dfMinY;
        pPoint[i].setX(x);
        pPoint[i].setY(y);
    }

    getShap(iCountPoint, pPoint, splineList, dfMinX, dfMinY);
}

void getShap(int nCtrlPntNum, QPointF *pPoint, QList<QPointF> &splineList, double dfMinX, double dfMinY)
{
    int i,j,k,stp,leg, m = nCtrlPntNum-1;
    double t0,t1,r0,r1, *o, *p, *q;
    QPointF *u, *v;

    o = new double  [nCtrlPntNum + 1];
    p = new double  [nCtrlPntNum + 1];
    q = new double  [nCtrlPntNum + 1];
    u = new QPointF [nCtrlPntNum + 1];
    v = new QPointF [nCtrlPntNum + 1];

    do // 计算弦长
    {
        j = 0;
        for (i = 1; i<= m; i++)
        {
            t0 = pPoint[i].x() - pPoint[i-1].x();
            t1 = pPoint[i].y() - pPoint[i-1].y();
            o[i] = sqrt(t0 * t0 + t1 * t1);
            if (o[i] < 2)
            {
                j = i;
                break;
            }
        }

        if (j > 0)
        {
            for (i = j; i <= m; i++)
            {
                pPoint[i].setX(pPoint[i+1].x());
                pPoint[i].setY(pPoint[i+1].y());
            }
            m--;
        }
    } while (j!=0);

    t0 = o[1]   + o[2];
    t1 = 2*o[1] * o[2]; // 边界条件 m[o] 和 m[N] 的构造

    u[0].setX((t0 * t0 * pPoint[1].x() - o[2] * o[2] * pPoint[0].x() - o[1] * o[1] * pPoint[2].y()) / t1 - pPoint[0].x());
    u[0].setY((t0 * t0 * pPoint[1].y() - o[2] * o[2] * pPoint[0].y() - o[1] * o[1] * pPoint[2].y()) / t1 - pPoint[0].y());
    t0 = sqrt(u[0].x() * u[0].x() + u[0].y() * u[0].y());

    u[0].setX(u[0].x() / t0);
    u[0].setY(u[0].y() / t0);
    t0 = o[m-1]    + o[m];
    t1 = 2*o[m-1]  * o[m];

    r0 = (t0 * t0 * pPoint[m-1].x() - o[m] * o[m] * pPoint[m-2].x() - o[m-1] * o[m-1] * pPoint[m].x()) / t1;
    r1 = (t0 * t0 * pPoint[m-1].y() - o[m] * o[m] * pPoint[m-2].y() - o[m-1] * o[m-1] * pPoint[m].y()) / t1;
    u[m].setX(pPoint[m].x() - r0);
    u[m].setY(pPoint[m].y() - r1);
    t0 = sqrt(u[m].x() * u[m].x() + u[m].y() * u[m].y());
    u[m].setX(u[m].x() / t0);
    u[m].setY(u[m].y() / t0);

    //计算 m 连续方程系数 C[i]
    p[1] = o[2] / (o[1] + o[2]);
    q[1] = 3;
    t0 = p[1] * (pPoint[1].x() - pPoint[0].x()) / o[1];
    t1 = p[1] * (pPoint[1].y() - pPoint[0].y()) / o[1];
    v[1].setX(4 * (t0 + (1-p[1]) * (pPoint[2].x() - pPoint[1].x()) / o[1+1]));
    v[1].setY(4 * (t1 + (1-p[1]) * (pPoint[2].y() - pPoint[1].y()) / o[1+1]));

    for (i=2; i<= (m-1); i++)
    {
        p[i] = o[i+1] / (o[i]+o[i+1]);
        q[i] = 3 - p[i] * (1 - p[i-1]) / q[i-1];

        t0 = p[i] * (pPoint[i].x() - pPoint[i-1].x()) / o[i];
        t1 = p[i] * (pPoint[i].y() - pPoint[i-1].y()) / o[i];

        v[i].setX(4 * (t0 + (1 - p[i]) * (pPoint[i+1].x() - pPoint[i].x()) / o[i+1]));
        v[i].setY(4 * (t1 + (1 - p[i]) * (pPoint[i+1].y() - pPoint[i].y()) / o[i+1]));
    }

    v[1].setX(v[1].x() - p[1] * u[0].x());
    v[1].setY(v[1].y() - p[1] * u[0].y());
    v[m-1].setX(v[m-1].x() - (1 - p[m-1]) * u[m].x());
    v[m-1].setY(v[m-1].y() - (1 - p[m-1]) * u[m].y());

    // 求解 m 连续方程, 获得 m[i]
    u[1].setX(v[1].x() / q[1]);
    u[1].setY(v[1].y() / q[1]);

    for (i = 2; i <= m-1; i++)
    {
        u[i].setX((v[i].x() - p[i] * u[i-1].x()) / q[i]);
        u[i].setY((v[i].y() - p[i] * u[i-1].y()) / q[i]);
    }

    for (i = m-2; i >= 1; i--)
    {
        u[i].setX(u[i].x() - u[i+1].x() * (1 - p[i]) / q[i]);
        u[i].setY(u[i].y() - u[i+1].y() * (1 - p[i]) / q[i]);
    }

    // 求得 M[j] j=0,1,...,N
    v[0].setX(4 * (pPoint[1].x() - pPoint[0].x()) / (o[1] * o[1]) - (3 * u[0].x() + u[1].x()) / o[1]);
    v[0].setY(4 * (pPoint[1].y() - pPoint[0].y()) / (o[1] * o[1]) - (3 * u[0].y() + u[1].y()) / o[1]);
    q[0]=0;

    for (i=1; i<= m; i++)
    {
        q[i] = 0;
        t0   = o[i] * o[i];
        v[i].setX(-4 * (pPoint[i].x() - pPoint[i-1].x()) / t0 + (3 * u[i].x() + u[i-1].x()) / o[i]);
        v[i].setY(-4 * (pPoint[i].y() - pPoint[i-1].y()) / t0 + (3 * u[i].y() + u[i-1].y()) / o[i]);
        for (j=1; j<= i; j++)
            q[i] = q[i] + o[j];
    }

    // o[j] j=0,1,...,N 表示半节点
    o[0]   = q[0];
    o[m+1] = q[m];

    for (i = 1; i<= m; i++)
        o[i] = (q[i-1] + q[i]) / 2;

    // 显示或绘之曲线
    QPointF suPoint;
    suPoint.setX(pPoint[0].x() +  dfMinX);
    suPoint.setY(pPoint[0].y() +  dfMinY);
    splineList.append(suPoint);
    //	pDC->MoveTo(lx1,ly1);

    for (i = 0; i< m; i++)
    {
        leg = (int)(o[i+1] - o[i]);
        stp = leg / 10;

        if (leg> 600)
            stp = leg / 60;

        if (leg> 900)
            stp = leg / 80;

        if (leg>1200)
            stp = leg / 100;

        if (leg > 2400)
            stp = leg / 120;

        if (leg>4800)
            stp = leg / 140;

        if (stp)
            k = leg/stp;
        else
            k = 0;

        for (j = 0; j<= k; j++)
        {
            r0 = o[i] + stp * j - q[i];
            suPoint.setX(pPoint[i].x() + r0 * (u[i].x() + v[i].x() / 2 * r0) +  dfMinX);
            suPoint.setY(pPoint[i].y() + r0 * (u[i].y() + v[i].y() / 2 * r0) +  dfMinY);
            splineList.append(suPoint);
            //pDC->LineTo(lx1,ly1);
        }
    }

    suPoint.setX(pPoint[m].x() +  dfMinX);
    suPoint.setY(pPoint[m].y() +  dfMinY);
    splineList.append(suPoint);
    //pDC->LineTo(lx1,ly1);

    delete o;
    delete p;
    delete q;
    delete u;
    delete v;
}

void getCurvePointFillLine(QList<QPointF> &inList, double indRunLen, QList<QPointF> &outList, int iSumParm, BYTE biLenLimit)
{
    QPointF dPoint1, dPoint2, dPoint3;
    double dTatol, dLen1, dLen2, dSpace;
    long lSum, lCount;

    //计算总的线段长
    int iCountPoint = inList.size();
    if(iCountPoint <= 0)
    {
        return;
    }

    getTotalDistanceFillLine(&inList, dTatol);
    if(dTatol == 0)
        return;

    if (biLenLimit == ADJUSTLINE_ADD_DUAN_LIMIT)
    {
        lSum  = iSumParm;
        if (lSum  < 1)
            lSum  = 1;
        dSpace = dTatol / lSum;
    }
    else if (iSumParm > 2)
    {
        lSum = iSumParm;
        dSpace = dTatol / (double)lSum;
    }
    else
    {
        if (biLenLimit == OBJECT_STITCHLEN_NEW_BIG)
        {
            lSum   = int(dTatol / indRunLen);
            dSpace = dTatol / lSum;

            if(lSum == 0)
                lSum = 1;
        }
        else if (biLenLimit == OBJECT_STITCHLEN_NEW_SAMALL)
        {
            lSum = doubleToLong(dTatol / indRunLen + 0.1667);
            dSpace = dTatol / (double)lSum;
            if(lSum == 0)
                lSum = 1;
        }
        else if (biLenLimit == OBJECT_STITCHLEN_NEW_SAME)
        {
            lSum = int(dTatol / indRunLen);
            dSpace = indRunLen;
            if(lSum == 0)
                lSum = 1;
        }
        else if (biLenLimit == LINEDUAN_STITCHLEN_LIMIT ||
                 biLenLimit == LINEDUAN_STITCHLEN_LIMIT_END)
        {
            lSum   = int(dTatol / indRunLen);
            dSpace = indRunLen;
        }
        else if (biLenLimit == LINEDUAN_NUM_LIMIT)
        {
            lSum   = int(dTatol / indRunLen);
            dSpace = dTatol / (double)lSum;
        }
        else
        {
            if (biLenLimit)
            {
                lSum = int(dTatol / indRunLen);
                if (lSum < 1)
                    lSum = doubleToLong(dTatol / indRunLen + 0.1667);
            }
            else
                lSum = doubleToLong(dTatol / indRunLen + 0.1667);

            if(lSum == 0)
                lSum = 1;

            dSpace = dTatol / (double)lSum;
        }
    }

    dPoint1 = inList[0];
    outList.append(dPoint1);//添加第一个点

    pointToPoint(dPoint1, dPoint2);
    dLen1 = dSpace;
    dLen2 = 0;
    int i = 0;
    for(lCount = 0; lCount < lSum; lCount++)
    {
        while(i < inList.size()-1 && dLen2 < dLen1)
        {
            dLen1 -= dLen2;
            pointToPoint(dPoint2, dPoint1);
            i++;
            dPoint2 = inList[i];
            distPointToPoint(dPoint1, dPoint2, dLen2);
        }
        if(dLen1 < dLen2)
        {
            getPointInSectFillLine(dPoint1, dPoint2, dLen1, dPoint3);
        }
        else
        {
            dPoint3.setX(dPoint2.x());
            dPoint3.setY(dPoint2.y());
        }
        outList.append(dPoint3);
        dLen2 -= dLen1;
        dLen1 = dSpace;
        pointToPoint(dPoint3, dPoint1);
    }

    if (biLenLimit == LINEDUAN_STITCHLEN_LIMIT_END ||
            biLenLimit == OBJECT_STITCHLEN_NEW_SAME)
    {
        if (fabs((lSum * indRunLen) - dTatol) > ZERO)
        {
            outList.append(inList.last());
        }
    }
}

int getTotalDistanceFillLine(QList<QPointF> *pPointList, double &dTotal)
{
    QPointF dPoint, dNext;
    double d;
    dTotal = 0;
    int i = 0;
    long lSum = (long)pPointList->count();
    if(lSum > 1)
    {
        while(i < pPointList->size())
        {
            dPoint = pPointList->at(i);
            i++;
            if(i < pPointList->size())
            {
                dNext = pPointList->at(i);
                distPointToPoint(dPoint, dNext, d);
                dTotal += d;
            }
            else
            {
                break;
            }
        }
    }
    return ERROR_NOTHING;
}

void pointToPoint(const QPointF &inPoint, QPointF &outPoint)
{
    outPoint.setX(inPoint.x());
    outPoint.setY(inPoint.y());
}

long doubleToLong(double indValue)
{
    return (long)round(indValue);
}

double round(double indValue)
{
    return floor(indValue + 0.5);
}

void distPointToPoint(const QPointF &p1, const QPointF &p2, double &outd)
{
    outd = disPointToPoint(p1.x(), p1.y(), p2.x(), p2.y());
}

bool getPointInSectFillLine(const QPointF &p1, const QPointF &p2, const double &d, QPointF &outp)
{
    bool bRes;
    QPointF dpoint[3];

    dpoint[0].setX(p1.x());
    dpoint[0].setY(p1.y());
    dpoint[1].setX(p2.x());
    dpoint[1].setY(p2.y());
    dpoint[2].setX(outp.x());
    dpoint[2].setY(outp.y());

    bRes = getPointAtSect(dpoint[0], dpoint[1], d, dpoint[2]);
    outp.setX(dpoint[2].x());
    outp.setY(dpoint[2].y());

    return bRes;
}

bool getPointAtSect(const QPointF &p1, const QPointF &p2, const double &d, QPointF &outp)
{
    double s = disPointToPoint(p1.x(), p1.y(), p2.x(), p2.y());
    if(fabs(s) < ZERO)
    {
        if(d < ZERO)
        {
            outp.setX(p1.x());
            outp.setY(p1.y());
        }
        return false;
    }
    outp.setX((p2.x() - p1.x()) * d / s + p1.x());
    outp.setY((p2.y() - p1.y()) * d / s + p1.y());

    return true;
}

double disPointToPoint(double x1, double y1, double x2, double y2)
{
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}

void getBezierPointList(double threex[], double threey[], s16 step, QList<QPointF> &outList)
{
    long k = 0;
    double sx,sy;
    Point2D cp[4];

    //传递参数
    for (s16 i = 0; i < 4; i++)
    {
        cp[i].x = threex[i];
        cp[i].y = threey[i];
    }

    //求控制点总长
    for (s16 i = 0; i < 3; i++)
    {
        sx = cp[i+1].x - cp[i].x;
        sy = cp[i+1].y - cp[i].y ;
        k +=  sqrt(sx*sx+sy*sy);  //分割点数= 总长(精度为0.1mm)
    }

    k = (long)((k / step)+1) * YUFENGE;  	//分割针步数
    Point2D curve;

    double dt;
    dt = 1.0 / ( k - 1 );		//分割分辨率

    QPointF p;
    for (int i = 0; i < k; i++)
    {
        curve = pointOnCubicBezier(cp, i*dt);
        p.setX(curve.x);
        p.setY(curve.y);
        outList.append(p);
    }
}

int getSplineMinMax(QList<QPointF> &ptList, double *pminx, double *pmaxx, double *pminy, double *pmaxy)
{
    QList<QPointF> splineListXY;//拟合后的点
    splineListXY.clear();

    double minx, miny, maxx, maxy;
    minx = S32_MAX;
    maxx = S32_MIN;
    miny = S32_MAX;
    maxy = S32_MIN;

    //读取样条线拟合控制点
    QPointF pSuPoint;
    int i = 0;
    int iCountPoint = ptList.size();

    //绘制二次累加弦长曲线
    QPointF pPoint[iCountPoint];
    double dfMinX, dfMinY;

    dfMinX = dfMinY=  0;

    while (i < iCountPoint)
    {
        pSuPoint = ptList.at(i);

        pPoint[i].setX(pSuPoint.x());
        pPoint[i].setY(pSuPoint.y());
        if (i == 0)
        {
            dfMinX =  pPoint[i].x();
            dfMinY =  pPoint[i].y();
        }
        else
        {
            if (dfMinX > pPoint[i].x())
                dfMinX = pPoint[i].x();

            if (dfMinY > pPoint[i].y())
                dfMinY = pPoint[i].y();
        }
        i++;
    }

    for (i = 0; i < iCountPoint; i++)
    {
        double x = pPoint[i].x() - dfMinX;
        double y = pPoint[i].y() - dfMinY;
        pPoint[i].setX(x);
        pPoint[i].setY(y);
    }

    getShap(iCountPoint, pPoint, splineListXY, dfMinX, dfMinY);

    for (i=0;i<splineListXY.size();i++)
    {
        if (minx > splineListXY[i].x())
        {
            minx = splineListXY[i].x();
        }
        if (maxx < splineListXY[i].x())
        {
            maxx = splineListXY[i].x();
        }
        if (miny > splineListXY[i].y())
        {
            miny = splineListXY[i].y();
        }
        if (maxy < splineListXY[i].y())
        {
            maxy = splineListXY[i].y();
        }
    }

    if (minx < *pminx)
    {
        *pminx = minx;
    }

    if (miny < *pminy)
    {
        *pminy = miny;
    }

    if (maxx > *pmaxx)
    {
        *pmaxx = maxx;
    }

    if (maxy > *pmaxy)
    {
        *pmaxy = maxy;
    }

    return 0;
}
